package org.duang.push;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;

import org.duang.db.Connection;
import org.duang.kit.ToolsKit;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WebSocketConnection implements Runnable  {
	private static Logger logger = LoggerFactory.getLogger(WebSocketConnection.class);
	private static Map<String, String> connMap = new HashMap<String,String>();
	protected WebSocketConnection socketConn; // 连接对象
	protected static ServerBootstrap bootstrap; 
	
	/**
	 * 创建WebSocket工厂
	 * 
	 * @param optionMap
	 *            连接参数Map
	 * @throws Exception
	 */
	public void connect(Map<String, String> map) throws Exception {
		synchronized (this) {
			if(ToolsKit.isNotEmpty(map)){
				connMap.putAll(map);
			}
			if(ToolsKit.isEmpty(socketConn)){
				socketConn = new WebSocketConnection();
			}
			socketConn.run();
		}
	}
	
	private Map<String, Object> getSocketOptionsMap() {
		Map<String, Object> map = new HashMap<String,Object>();
		map.put("child.tcpNodelay", true);
		map.put("child.keepAlive", true);
		return map;
	}

	@Override
	public void run() {
		ChannelFactory channelFactory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
		if(ToolsKit.isEmpty(channelFactory)){
			throw new NullPointerException("create socket channel factory fail!");
		}
		ChannelPipelineFactory pipelineFactory = new WebSocketServerPipelineFactory();
		if(ToolsKit.isEmpty(pipelineFactory)){
			throw new NullPointerException("create socket pipeline factory fail!");
		}
		try {
			bootstrap = new ServerBootstrap();
			bootstrap.setFactory(channelFactory);
			bootstrap.setPipelineFactory(pipelineFactory);
			bootstrap.setOptions(getSocketOptionsMap());
			bootstrap.bind(new InetSocketAddress(connMap.get(Connection.HOST_FIELD), Integer.parseInt(connMap.get(Connection.PORT_FIELD))));
			logger.debug("bootstrap bind success!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
